package com.avengers.core.thread;

import com.avengers.job.JobNoKit;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;

import java.util.concurrent.*;

/**
 * @author yu.wang
 * @since 2019/5/10 9:53 AM
 **/
public class ThreadPoolFactory {
    private static final int DEFAULT_BLOCK_SIZE = 20000;
    private static final int DEFAULT_SIZE = 1;
    private static final long DEFAULT_KEEP_ALIVE_TIME = 0L;

    public static ExecutorService create() {
        return create(DEFAULT_SIZE);
    }

    public static ExecutorService create(int size) {
        return create(size, size, DEFAULT_KEEP_ALIVE_TIME, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(DEFAULT_BLOCK_SIZE),
                new ThreadPoolExecutor.AbortPolicy());
    }

    public static ExecutorService create(int coePoolSize, int maximumPoolSize) {
        return create(coePoolSize, maximumPoolSize, DEFAULT_KEEP_ALIVE_TIME, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(DEFAULT_BLOCK_SIZE),
                new ThreadPoolExecutor.AbortPolicy());
    }

    public static ExecutorService create(int size, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
        return create(size, size, DEFAULT_KEEP_ALIVE_TIME, TimeUnit.SECONDS, workQueue, handler);
    }

    public static ExecutorService create(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
        return new AvengersThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
    }

    public static ScheduledExecutorService createScheduled() {
        return createScheduled("", 1, Boolean.FALSE);
    }

    public static ScheduledExecutorService createScheduled(boolean daemon) {
        return createScheduled("", 1, daemon);
    }

    public static ScheduledExecutorService createScheduled(int size, boolean daemon) {
        return createScheduled("" + System.currentTimeMillis(), size, daemon);
    }

    public static ScheduledExecutorService createScheduled(int size) {
        return createScheduled("" + System.currentTimeMillis(), size, Boolean.FALSE);
    }

    public static ScheduledExecutorService createScheduled(String threadPoolName, int size) {
        return createScheduled(threadPoolName, size, Boolean.FALSE);
    }

    public static ScheduledExecutorService createScheduled(String threadPoolName, int size, boolean daemon) {
        return new ScheduledAvengersThreadPoolExecutor(size,
                new BasicThreadFactory.Builder().namingPattern(genThreadName(threadPoolName)).daemon(daemon).build());
    }

    private static String genThreadName(String threadPoolName) {
        String jobNo = JobNoKit.get();
        return (null == threadPoolName || threadPoolName.isEmpty() ? null == jobNo || jobNo.isEmpty() ? "" : jobNo : threadPoolName) + System.currentTimeMillis() + "-pool-%d";
    }
}